package cn.fuxi2022.auth.controller;

import cn.fuxi2022.auth.service.GroupStudentService;
import cn.fuxi2022.model.empty.auth.GroupStudent;
import cn.fuxi2022.model.resp.R;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


@Slf4j
@RestController
@RequestMapping("/applets/oauth2")
public class AppletsLoginByOauth2 {


    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private GroupStudentService groupStudentService;

    /**
     * 授权回调获取用户信息接口地址
     */
    @Value("${wx.mp.userInfoUrl}")
    private String userInfoUrl;


//    @GetMapping("/userInfo/MP_verify_vidR0mY49lZlmhqB.txt")
//    public String check() {
//        return "vidR0mY49lZlmhqB";
//    }

    /**
     * 第一步：用户同意授权，获取code
     * 微信授权，引导用户重定向至微信授权页面
     *
     * @return 重定向至微信授权接口
     */
    @GetMapping("/authorize")
    public R authorize() {
        // 重定向，引导关注者打开如下页面：
        // https://open.weixin.qq.com/connect/oauth2/authorize?
        // appid=wxf0e81c3bee622d60&
        // redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&
        // response_type=code&
        // scope=snsapi_userinfo&
        // state=STATE#wechat_redirect
        // redirectURI：微信授权后，将该指定接口, 该接口将获取到code，根据code获取用户信息，再重定向至用户的页面
        // String scope：当前方式为snsapi_userinfo,表示当前类型为`获取用户的基本信息`
        // String state：当前用户前端的地址，授权完成后，将返回该页面
        String redirectURL = wxMpService.
                oauth2buildAuthorizationUrl(userInfoUrl,
                        WxConsts.OAUTH2_SCOPE_USER_INFO, "authorize");
        return R.ok().data("url", redirectURL);
    }

    /**
     * 第二步：通过 code 换取网页授权access_token + 第三步：拉取用户信息(需 scope 为 snsapi_userinfo)
     * <p>
     * 微信回调该接口，将code携带过来，根据code获取用户信息
     * 如果用户同意授权，页面将跳转至 redirect_uri(当前接口)/?code=CODE&state=STATE
     *
     * @param code      code作为换取access_token的票据，获取用户信息
     * @param returnUrl 微信的state，当前用户的前端地址
     * @return 重定向用户前端的地址，即returnUrl
     */
    @GetMapping("/userInfo")
    public R userInfo(@RequestParam("code") String code,
                      @RequestParam("state") String returnUrl) {

        // 第二步：通过 code 换取网页授权access_token 与 用户的openId
        WxMpUser wxMpUser;
        try {
            WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);

            // 第三步：拉取用户信息(需 scope 为 snsapi_userinfo)
            // 开发者可以通过access_token和 openid 拉取用户信息
            wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, "zh_CN");

        } catch (WxErrorException e) {
            // e.printStackTrace();
            // 授权失败，就让用户再授权一次
            return R.error("当前授权失败，请等待小程序响应后，重新授权");
        }

        // 将用户信息存储进数据库（不演示）
        // 注意，需要先根据openId判断用户是否注册，不存在就执行注册业务，存在就执行更新用户信息业务
        // 根据unionId查询数据库，获取需要补充完整的用户
        // log.info("当前用户信息为：{}", JSON.toJSONString(wxMpUser));
        String unionId = wxMpUser.getUnionId();
        String nickname = wxMpUser.getNickname();
        String openId = wxMpUser.getOpenId();
        String headImgUrl = wxMpUser.getHeadImgUrl();

        LambdaQueryWrapper<GroupStudent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GroupStudent::getUnionId, unionId);

        GroupStudent student = groupStudentService.getOne(wrapper);

        if (ObjectUtils.isEmpty(student) || !StringUtils.hasText(student.getId())) {
            return R.error("当前用户未注册，请注册");
        }

        student.setAvatar(headImgUrl);
        student.setOpenidGz(openId);
        student.setNickname(nickname);

        groupStudentService.updateById(student);

        return R.ok("获取信息成功，请等待小程序响应，若没有响应，手动退出即可");
    }
}
